# -*- coding:utf-8 -*-
from utils.views import WdListAPIView, WdRetrieveUpdateAPIView, WdUpdateAPIView, WdAPIView, WdCreateAPIView, WdRetrieveAPIView

from models import Task, DataStorage
from serializer import AppTaskListSerializer, AppTaskSerializer, AppTaskStatusSerializer, DataStorageSerializer
from django.db.models import Q
from utils.response import ErrorCode
import datetime
from utils.response import general_json_response
from rest_framework import status
import json
from ElevatorAdmin.tasks import first_maintain_registry, end_task, estate_confirm_registry, submit, first_maintain_registry_V2
from users.models import CompanyInfo, Registry, Person, PersonPositions
from basic.models import ElevatorInfo
from utils.logger import get_logger
import operator
from users.models import CompanyAutoSubmit


logger = get_logger(__name__)


class AppTaskListView(WdListAPIView):
    model = Task
    serializer_class = AppTaskListSerializer
    GET_CHECK_REQUEST_PARAMETER = ('status', )
    SEARCH_FIELDS = ('sn', )
    FOREIGN_SEARCH_FIELD_MAP = {'elevator': {"key_model": ElevatorInfo, "search_for":
                                             ["register_code", "property_company_name", "internal_no"]}}

    def get_queryset(self):
        today = datetime.date.today()
        user = self.request.user
        qs = super(AppTaskListView, self).get_queryset()
        st = self.request.GET.get('status', None)
        if user.role == 30:
            company = user.company_person.company
            if int(st) == 30:
                qs = qs.filter(status__in=(30, 50, 60, 70, 80, 90, 110, 120, 130, 140), elevator__property_company=company)
            elif int(st) == 40:
                qs = qs.filter(status=40, elevator__property_company=company)
            return qs
        p = user.person
        elevator = self.request.GET.get('elevator', None)
        if int(st) == 10:
            qs = qs.filter(status=10, day__gte=today)
        elif int(st) == 20:
            qs = qs.filter(status__in=(20, 100))
        elif int(st) == 30:
            qs = qs.filter(status__in=(30, 40, 50, 60, 70, 80, 90, 110, 120, 130, 140))
        elif int(st) == 40:
            qs = qs.filter(status__gte=40)
        # qs = qs.filter(Q(worker_1=p.id) | Q(worker_2=p.id))
        ids = []
        for i in qs:
            worker = i.worker
            worker = json.loads(worker)
            if p.id in worker:
                ids.append(i.id)
        qs = Task.objects.filter_active(id__in=ids).order_by('day')
        if elevator:
            qs = qs.filter(elevator=int(elevator))
        if int(st) == 30:
            qs = qs.order_by("-update_time")
        return qs

    def qs_filter(self, qs):
        # qs = super(AppTaskListView, self).qs_filter(qs)
        time_from = self.request.GET.get("time_from", None)
        time_to = self.request.GET.get("time_to", None)
        if time_from and time_to:
            qs = qs.filter(day__gte=time_from, day__lte=time_to)
        return qs

    def process_foreign_search(self):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        search_sql = []
        for key_name in self.FOREIGN_SEARCH_FIELD_MAP:
            search_for = self.FOREIGN_SEARCH_FIELD_MAP.get(key_name).get('search_for')
            key_model = self.FOREIGN_SEARCH_FIELD_MAP.get(key_name).get("key_model")
            for foreign_field in search_for:
                ids = key_model.objects.filter(**{"%s__icontains" % foreign_field: key_words})
                search_sql.append(Q(**{"%s__in" % key_name: ids}))
        return search_sql

    def qs_search(self, qs):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        if key_words is None or not key_words:
            return qs
        search_sql = []
        for search_field in self.SEARCH_FIELDS:
            search_sql.append(Q(**{"%s__icontains" % search_field: key_words}))
        search_sql += self.process_foreign_search()
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs


class AppTaskStatusView(WdUpdateAPIView):

    model = Task
    serializer_class = AppTaskStatusSerializer
    POST_CHECK_REQUEST_PARAMETER = ('qr_code', )

    def post_check_parameter(self, kwargs):
        code = super(AppTaskStatusView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        qr_code = self.request.data.get('qr_code', None)
        task = self.get_object()
        e = task.elevator
        if qr_code == e.qr_code:
            print u'验证成功'
            user = self.request.user
            person = user.person
            company = user.person.company
            register_code = first_maintain_registry_V2(company.link_account, company.link_token, task.id, user.person)
            if register_code:
                return register_code
            self.request.data['status'] = 20
            self.request.data.update({"maintain_signature": user.sign_image})
            self.request.data.update({"maintainer_name": user.real_name})
            self.request.data.update({"maintainer_id": person.id})
        else:
            print u'验证失败'
            code = ErrorCode.INVALID_INPUT
        return code


class AppPropertyTaskStatusView(WdUpdateAPIView):
    model = Task
    serializer_class = AppTaskStatusSerializer
    POST_CHECK_REQUEST_PARAMETER = ('estate_confirm', )

    def post_check_parameter(self, kwargs):
        code = super(AppPropertyTaskStatusView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        task = self.get_object()
        user = self.request.user
        if user.role == 10:
            company = user.person.company
        else:
            use_company = user.company_person.company
            company = CompanyInfo.objects.get(id=use_company.service_id)
        signature = self.request.data.get('signature', None)
        if not signature:
            signature = user.sign_image
            self.request.data['signature'] = signature
        estate_confirm = self.request.data.get('estate_confirm', None)
        if task.status in (30, 80):
            if not company.link_account and not company.link_token:
                register_code = ErrorCode.SUCCESS
            else:
                register_code = estate_confirm_registry(company.link_account, company.link_token, task.id, signature, estate_confirm)
            if register_code:
                task.save()
                return register_code
            self.request.data['status'] = 40
        property_comfirm_time = datetime.datetime.now()
        self.request.data['property_comfirm_time'] = property_comfirm_time
        # if not signature:
        #     signature = user.sign_image
        #     self.request.data['signature'] = signature
        return code


class AppTaskView(WdRetrieveUpdateAPIView):

    model = Task
    p_serializer_class = AppTaskSerializer
    serializer_class = AppTaskListSerializer
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True
    POST_CHECK_REQUEST_PARAMETER = ("result", )

    def post_check_parameter(self, kwargs):
        code = super(AppTaskView, self).post_check_parameter(kwargs)
        if code != ErrorCode.SUCCESS:
            return code
        self.request.data['task_end_time'] = datetime.datetime.now()
        task = self.get_object()
        user = self.request.user
        company = user.person.company
        result = self.request.data.get('result')
        register_code = end_task(company.link_account, company.link_token, task.id, user.sign_image, result, user.person)
        logger.info("task_id: %s, code: %s " % (task.id, register_code))
        if register_code:
            task.save()
            return register_code
        self.request.data['status'] = 30
        lng = self.request.data.pop('lng', None)
        lat = self.request.data.pop('lat', None)
        if lng:
            self.request.data['lng'] = str(lng)
        self.request.data['task_end_time'] = datetime.datetime.now()
        if lat:
            self.request.data['lat'] = str(lat)
        return code


class AppWbItemsView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        from ElevatorAdmin.wbitems import items
        task_id = self.request.GET.get('task_id', None)
        if not task_id:
            wb_items = items['190']
        else:
            task = Task.objects.get(id=task_id)
            maintain_type = task.maintain_type
            multiple = (maintain_type % 40) // 10
            if multiple == 0:
                l = [maintain_type - 20, maintain_type - 10, maintain_type]
            elif multiple == 1:
                l = [maintain_type, maintain_type + 10, maintain_type + 20, maintain_type + 30]
            elif multiple == 2:
                l = [maintain_type,  maintain_type + 10]
            else:
                l = [maintain_type]
            wb_items = []
            for i in l:
                wb_items += items[str(i)]
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, wb_items)


class AppPositionView(WdListAPIView):

    def get(self, request, *args, **kwargs):
        from ElevatorAdmin.settings import PHOTO_POSITION
        values = PHOTO_POSITION.values()
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, values)


class AppTaskScanView(WdAPIView):

    def post(self, request, *args, **kwargs):
        today = datetime.date.today()
        qr_code = self.request.data.get('qr_code', None)
        if not qr_code:
            return general_json_response(status.HTTP_200_OK, ErrorCode.INVALID_INPUT, u'参数不存在')
        user = self.request.user
        if user.role == 10:
            person = user.person
            elevator = ElevatorInfo.objects.filter_active(qr_code=qr_code, maintain_company=user.person.company,
                                                          registry_status=20, usage_status=10).first()
            if not elevator:
                # 是否备案 是否绑定备案 是否在使用中
                return general_json_response(status.HTTP_200_OK, ErrorCode.ELEVATOR_NOT_EXIST, u'电梯不存在')
            tasks = Task.objects.filter_active(elevator=elevator)
            l = []
            for task in tasks:
                worker = json.loads(task.worker)
                if person.id in worker:
                    l.append(task.id)
            t = Task.objects.filter_active(id__in=l, day__gte=today).order_by('day').first()
            if not t:
                return general_json_response(status.HTTP_200_OK, ErrorCode.TASK_NOT_EXIST, u'工单不存在')
            elif t.status in [20, 30]:
                return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, t.id)
            elif t.status >= 40:
                return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, t.id)
            else:
                company = person.company
                register_code = first_maintain_registry_V2(company.link_account, company.link_token, t.id, person)
                if register_code == ErrorCode.SUCCESS:
                    t.status = 20
                    t.maintain_signature = user.sign_image
                    t.maintainer_name = user.real_name
                    t.maintainer_id = person.id
                    t.save(update_fields=['status', 'maintain_signature', 'maintainer_name', 'maintainer_id'])
                    return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, t.id)
                elif register_code == ErrorCode.FIRST_MAINTAIN_REGISTER_COMPLETE:
                    return general_json_response(status.HTTP_200_OK, ErrorCode.FIRST_MAINTAIN_REGISTER_COMPLETE,
                                                 u'由于此梯首次维保，请2分钟后重新二次扫码')
                else:
                    register = Registry.objects.filter(type_for_reg='Task', reg_obj_id=t.id).last()
                    msg = register.msg if register else u'未找到失败原因'
                    return general_json_response(status.HTTP_200_OK, ErrorCode.FIRST_MAINTAIN_REGISTER_FAIL, msg)
        else:
            company = user.company_person.company
            elevator = ElevatorInfo.objects.filter_active(qr_code=qr_code, property_company=company)
            if not elevator:
                return general_json_response(status.HTTP_200_OK, ErrorCode.ELEVATOR_NOT_EXIST, u'无此电梯')
            t = Task.objects.filter_active(status=30, elevator=elevator).order_by('day').first()
            if not t:
                return general_json_response(status.HTTP_200_OK, ErrorCode.TASK_NOT_EXIST, u'无待确认工单')
            # worker = t.worker
            # worker = json.loads(worker)
            # l = len(worker)
            # w = []
            # for i in range(l):
            #     try:
            #         person_id = worker[i]
            #         p = Person.objects.get(id=person_id)
            #         k = "worker_" + str(i + 1)
            #         w.append({k: person_id, "name": p.auth_user.real_name})
            #     except Exception as e:
            #         print e
            #         print u"维保人员被删除"
            # #
            # data = {"id": t.id, "elevator_name": elevator.elevator_name, "elevator_no": elevator.elevator_no,
            #         "maintain_type": t.get_maintain_type_display(), "day": str(t.day), "status": t.status,
            #         "sn": t.sn, "create_time": t.create_time.strftime("%Y-%m-%d %H:%M:%S"), "elevator": elevator.id,
            #         "task_end_time": t.task_end_time.strftime("%Y-%m-%d %H:%M:%S") if t.task_end_time else "",
            #         "result": t.result, "estate_confirm": t.estate_confirm, "desc": t.desc, "t_lng": t.lng,
            #         "t_lat": t.lat, "register_code": elevator.register_code, "use_company": company.name,
            #         "workers_all": w}
            return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, t.id)


class AppDataStorageCreateView(WdCreateAPIView, WdRetrieveAPIView):

    model = DataStorage
    serializer_class = DataStorageSerializer
    POST_DATA_ID_RESPONSE = True
    POST_DATA_RESPONSE = True

    def post_check_parameter(self, kwargs):
        user = self.request.user
        service_id = user.person.company.id
        person_positon = PersonPositions.objects.filter(person=user.person, is_new=True).first()
        if person_positon:
            self.request.data.update({'position': person_positon.position})
        self.request.data.update({'update_by': user.id, 'service_id': service_id})
        code = super(AppDataStorageCreateView, self).post_check_parameter(kwargs)
        return code

    def perform_create(self, serializer):
        super(AppDataStorageCreateView, self).perform_create(serializer)
        obj = self.create_obj
        task = obj.task
        if obj.position:
            task.position = obj.position
            task.save()

    def get(self, request, *args, **kwargs):
        task = self.request.GET.get('task')
        task = Task.objects.get(id=int(task))
        data_storage = DataStorage.objects.filter_active(task=task).order_by('-id').first()
        data = DataStorageSerializer(instance=data_storage, many=False).data
        data.pop('update_by')
        data.pop('service_id')
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class AppCodeMapToContent(WdListAPIView):
    """ 获取电梯对应的维保项 """

    def get(self, request, *args, **kwargs):
        from ElevatorAdmin.wbitems import items
        # need_pull = self.request.data.get("need_pull", None)
        today = datetime.date.today()
        user = self.request.user
        data = dict()
        if user.role == 10:
            person = user.person
            company = person.company
            tasks = Task.objects.filter_active(day__gte=today, status__lt=30, elevator__maintain_company=company)
            ids = []
            for i in tasks:
                workers = json.loads(i.worker)
                if person.id in workers:
                    ids.append(i.id)
            # 遍历工单，查询是不是某个工单的维保人员 离线版 有可能出现电梯维保完了，但是工单没有了 或者 之前的工单已提交市局
            tasks = tasks.filter(id__in=ids).order_by('-create_time')

            maintain_types = [90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240]
            content = dict()
            dic = dict()
            t = list()
            # if need_pull:
            for maintain_type in maintain_types:
                multiple = (maintain_type % 40) // 10
                if multiple == 0:
                    l = [maintain_type - 20, maintain_type - 10, maintain_type]
                elif multiple == 1:
                    l = [maintain_type, maintain_type + 10, maintain_type + 20, maintain_type + 30]
                elif multiple == 2:
                    l = [maintain_type, maintain_type + 10]
                else:
                    l = [maintain_type]
                wb_items = []
                for i in l:
                    wb_items += items[str(i)]
                content[maintain_type] = wb_items
            # if not tasks:
            #     return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, {"content": content, "elevators": t})
            i = 0
            for task in tasks:
                if task.elevator.qr_code not in dic.keys():
                    t.append({"qr_code": task.elevator.qr_code, "register_code": task.elevator.register_code,
                              "elevator_name": task.elevator.elevator_name, "elevator_no": task.elevator.elevator_no,
                              "task": [{"maintain_type": task.maintain_type, "id": task.id, "sn": task.sn,
                                        "day": str(task.day), "property_company": task.elevator.property_company.name}]})
                    dic[task.elevator.qr_code] = i
                    i += 1
                else:
                    obj = t[dic[task.elevator.qr_code]]
                    obj["task"].append({"maintain_type": task.maintain_type, "id": task.id, "sn": task.sn})

            data["content"] = content
            data["elevators"] = t
        else:
            data["content"] = []
            data["elevators"] = []

        service_id = user.service_id
        # eis = ElevatorInfo.objects.filter_active(service_id=service_id).values("register_code", "internal_no",
        #                                                                        "factory_no", "address",
        #                                                                        "maintain_company_name",
        #                                                                        "property_company_name", "num",
        #                                                                        "manufacturer_company_name", "qr_code",
        #                                                                        "next_yearly_inspection_date")
        es = ElevatorInfo.objects.filter_active(service_id=service_id)
        today = datetime.date.today()
        eis = []
        for e in es:
            task = e.tasks.filter(day__gte=today, status__in=(10, 50, 100)).first()
            eis.append({
                "register_code": e.register_code,
                "internal_no": e.internal_no,
                "factory_no": e.factory_no,
                "address": e.address,
                "maintain_company_name": e.maintain_company_name,
                "property_company_name": e.property_company_name,
                "num": e.num,
                "manufacturer_company_name": e.manufacturer_company_name,
                "qr_code": e.qr_code,
                "next_yearly_inspection_date": e.next_yearly_inspection_date,
                "next_maintain_date": task.day if task else None,
                "id": e.id
            })
        data['eis'] = eis
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, data)


class AppWbSubmitView(WdAPIView):
    """维保人员 和 使用单位提交"""

    def post(self, request, *args, **kwargs):
        today = datetime.datetime.today()
        user = self.request.user
        logger.info("app task submit")
        logger.info(user.real_name)
        # qr_code = self.request.data.get('qr_code', None)
        task = self.request.data.get('task', None)
        need_add_time = self.request.data.get("need_add_time", None)
        task_start_time = self.request.data.get("task_start_time", None)

        # 物业提交的字段
        estate_confirm = self.request.data.get('estate_confirm', None)
        signature = self.request.data.get('signature', None)

        # 维保人员提交的字段
        result = self.request.data.get('result', None)
        desc = self.request.data.get('desc', None)
        maintain_signature = self.request.data.get('maintain_signature', None)

        if not task:
            return general_json_response(status.HTTP_200_OK, ErrorCode.INVALID_INPUT, u'task为必传参数')
        # 通过维保人员app提交数据，分为维保人员和物业两种类型
        person = user.person
        # tasks = Task.objects.filter_active(elevator__qr_code=qr_code, day__gte=today, status=10)
        # ids = []
        # for i in tasks:
        #     workers = json.loads(i.worker)
        #     if person.id in workers:
        #         ids.append(i.id)
        # # 遍历工单，查询是不是某个工单的维保人员 离线版 有可能出现电梯维保完了，但是工单没有了 或者 之前的工单已提交市局
        # t = tasks.filter(id__in=ids).order_by('create_time').first()
        t = Task.objects.filter_active(id=task).first()
        if not t:
            return general_json_response(status.HTTP_200_OK, ErrorCode.TASK_NOT_EXIST, u'工单不存在')
        if t.status > 20:
            return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)
        # 查询是否自动提交
        company = t.elevator.maintain_company
        cas = CompanyAutoSubmit.objects.filter_active(company=company).first()
        # 维保人员单独提交 维保人员和物业人员同时提交

        if task_start_time:
            t.task_start_time = task_start_time
        # 维保人员单独提交
        if not estate_confirm and result:
            t.task_end_time = datetime.datetime.now()
            t.result = result
            t.desc = desc
            t.maintain_signature = maintain_signature if maintain_signature else user.sign_image
            t.maintainer_name = user.real_name
            t.maintainer_id = person.id
            t.estate_confirm = None
            t.signature = None
            t.property_comfirm_time = None
            if cas and not cas.auto_submit:
                t.status = 50
                t.save()
            else:
                t.status = 60
                t.save()
                submit.delay(t.id)
            return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)
        # 同时提交
        elif result and estate_confirm:
            t.estate_confirm = estate_confirm
            t.signature = signature
            t.property_comfirm_time = datetime.datetime.now()
            t.task_end_time = datetime.datetime.now()
            t.result = result
            t.maintain_signature = user.sign_image
            t.maintainer_name = user.real_name
            t.maintainer_id = person.id
            if cas and not cas.auto_submit:
                t.status = 50
                t.save()
            else:
                t.status = 60
                t.save()
                submit.delay(t.id, True)
            return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)
        else:
            return general_json_response(status.HTTP_200_OK, ErrorCode.INVALID_INPUT, u'result and estate_confirm 至少传一个')


class AppUpdateTaskForMeView(WdAPIView):
    """ 修改管理员打回来的工单"""
    def post(self, request, *args, **kwargs):
        result = self.request.data.get("result", None)
        task = self.request.data.get("task", None)
        if not result or not task:
            return general_json_response(status.HTTP_200_OK, ErrorCode.INVALID_INPUT, u"result和task 为必传字段")
        task = Task.objects.filter_active(id=task).first()
        if not task:
            return general_json_response(status.HTTP_200_OK, ErrorCode.INVALID_INPUT, u"工单不存在")
        company = task.elevator.maintain_company
        cas = CompanyAutoSubmit.objects.filter_active(company=company).first()
        task.result = result
        task.estate_confirm = None
        task.maintain_signature = self.request.user.sign_image
        task.transfer_to = None
        task.property_comfirm_time = None
        task.task_end_time = datetime.datetime.now()
        task.signature = None
        task.maintainer_name = self.request.user.real_name
        task.maintainer_id = self.request.user.person.id
        if cas and not cas.auto_submit:
            task.status = 50
            task.save()
        else:
            task.status = 60
            task.save()
            submit.delay(task.id)
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS)


class AppCountForMeView(WdAPIView):

    def get(self, request, *args, **kwargs):
        com = request.user.person.company
        count = Task.objects.filter_active(service_id=com.id, transfer_to=request.user.id).count()
        return general_json_response(status.HTTP_200_OK, ErrorCode.SUCCESS, count)


class AppGetForMeView(WdListAPIView):
    """ 获取维保管理员转发过来的工单"""

    model = Task
    serializer_class = AppTaskListSerializer
    SEARCH_FIELDS = ('sn',)
    FOREIGN_SEARCH_FIELD_MAP = {'elevator': {"key_model": ElevatorInfo, "search_for":
        ["register_code", "property_company_name", "internal_no"]}}

    def get_queryset(self):
        qs = super(AppGetForMeView, self).get_queryset()
        print self.request.user.id
        qs = qs.filter(transfer_to=self.request.user.id)
        return qs

    def qs_filter(self, qs):
        # qs = super(AppTaskListView, self).qs_filter(qs)
        time_from = self.request.GET.get("time_from", None)
        time_to = self.request.GET.get("time_to", None)
        if time_from and time_to:
            qs = qs.filter(day__gte=time_from, day__lte=time_to)
        return qs

    def process_foreign_search(self):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        search_sql = []
        for key_name in self.FOREIGN_SEARCH_FIELD_MAP:
            search_for = self.FOREIGN_SEARCH_FIELD_MAP.get(key_name).get('search_for')
            key_model = self.FOREIGN_SEARCH_FIELD_MAP.get(key_name).get("key_model")
            for foreign_field in search_for:
                ids = key_model.objects.filter(**{"%s__icontains" % foreign_field: key_words})
                search_sql.append(Q(**{"%s__in" % key_name: ids}))
        return search_sql

    def qs_search(self, qs):
        key_words = self.request.GET.get(self.SEARCH_KEY, None)
        if key_words is None or not key_words:
            return qs
        search_sql = []
        for search_field in self.SEARCH_FIELDS:
            search_sql.append(Q(**{"%s__icontains" % search_field: key_words}))
        search_sql += self.process_foreign_search()
        if len(search_sql) == 0:
            return qs
        else:
            query = reduce(operator.or_, search_sql)
            qs = qs.filter(query)
        return qs


















